home *** CD-ROM | disk | FTP | other *** search
/ Komputer for Alle 2004 #2 / K-CD-2-2004.ISO / OpenOffice Sv / f_0397 / python-core-2.2.2 / lib / dis.py < prev    next >
Encoding:
Python Source  |  2003-07-18  |  8.9 KB  |  328 lines

  1. """Disassembler of Python byte code into mnemonics."""
  2.  
  3. import sys
  4. import types
  5.  
  6. __all__ = ["dis","disassemble","distb","disco","opname","cmp_op",
  7.            "hasconst","hasname","hasjrel","hasjabs","haslocal",
  8.            "hascompare", "hasfree"]
  9.  
  10. def dis(x=None):
  11.     """Disassemble classes, methods, functions, or code.
  12.  
  13.     With no argument, disassemble the last traceback.
  14.  
  15.     """
  16.     if not x:
  17.         distb()
  18.         return
  19.     if type(x) is types.InstanceType:
  20.         x = x.__class__
  21.     if hasattr(x, 'im_func'):
  22.         x = x.im_func
  23.     if hasattr(x, 'func_code'):
  24.         x = x.func_code
  25.     if hasattr(x, '__dict__'):
  26.         items = x.__dict__.items()
  27.         items.sort()
  28.         for name, x1 in items:
  29.             if type(x1) in (types.MethodType,
  30.                             types.FunctionType,
  31.                             types.CodeType):
  32.                 print "Disassembly of %s:" % name
  33.                 try:
  34.                     dis(x1)
  35.                 except TypeError, msg:
  36.                     print "Sorry:", msg
  37.                 print
  38.     elif hasattr(x, 'co_code'):
  39.         disassemble(x)
  40.     else:
  41.         raise TypeError, \
  42.               "don't know how to disassemble %s objects" % \
  43.               type(x).__name__
  44.  
  45. def distb(tb=None):
  46.     """Disassemble a traceback (default: last traceback)."""
  47.     if not tb:
  48.         try:
  49.             tb = sys.last_traceback
  50.         except AttributeError:
  51.             raise RuntimeError, "no last traceback to disassemble"
  52.         while tb.tb_next: tb = tb.tb_next
  53.     disassemble(tb.tb_frame.f_code, tb.tb_lasti)
  54.  
  55. def disassemble(co, lasti=-1):
  56.     """Disassemble a code object."""
  57.     code = co.co_code
  58.     labels = findlabels(code)
  59.     n = len(code)
  60.     i = 0
  61.     extended_arg = 0
  62.     free = None
  63.     while i < n:
  64.         c = code[i]
  65.         op = ord(c)
  66.         if op == SET_LINENO and i > 0: print # Extra blank line
  67.         if i == lasti: print '-->',
  68.         else: print '   ',
  69.         if i in labels: print '>>',
  70.         else: print '  ',
  71.         print `i`.rjust(4),
  72.         print opname[op].ljust(20),
  73.         i = i+1
  74.         if op >= HAVE_ARGUMENT:
  75.             oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg
  76.             extended_arg = 0
  77.             i = i+2
  78.             if op == EXTENDED_ARG:
  79.                 extended_arg = oparg*65536L
  80.             print `oparg`.rjust(5),
  81.             if op in hasconst:
  82.                 print '(' + `co.co_consts[oparg]` + ')',
  83.             elif op in hasname:
  84.                 print '(' + co.co_names[oparg] + ')',
  85.             elif op in hasjrel:
  86.                 print '(to ' + `i + oparg` + ')',
  87.             elif op in haslocal:
  88.                 print '(' + co.co_varnames[oparg] + ')',
  89.             elif op in hascompare:
  90.                 print '(' + cmp_op[oparg] + ')',
  91.             elif op in hasfree:
  92.                 if free is None:
  93.                     free = co.co_cellvars + co.co_freevars
  94.                 print '(' + free[oparg] + ')',
  95.         print
  96.  
  97. disco = disassemble                     # XXX For backwards compatibility
  98.  
  99. def findlabels(code):
  100.     """Detect all offsets in a byte code which are jump targets.
  101.  
  102.     Return the list of offsets.
  103.  
  104.     """
  105.     labels = []
  106.     n = len(code)
  107.     i = 0
  108.     while i < n:
  109.         c = code[i]
  110.         op = ord(c)
  111.         i = i+1
  112.         if op >= HAVE_ARGUMENT:
  113.             oparg = ord(code[i]) + ord(code[i+1])*256
  114.             i = i+2
  115.             label = -1
  116.             if op in hasjrel:
  117.                 label = i+oparg
  118.             elif op in hasjabs:
  119.                 label = oparg
  120.             if label >= 0:
  121.                 if label not in labels:
  122.                     labels.append(label)
  123.     return labels
  124.  
  125. cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is',
  126.         'is not', 'exception match', 'BAD')
  127.  
  128. hasconst = []
  129. hasname = []
  130. hasjrel = []
  131. hasjabs = []
  132. haslocal = []
  133. hascompare = []
  134. hasfree = []
  135.  
  136. opname = [''] * 256
  137. for op in range(256): opname[op] = '<' + `op` + '>'
  138.  
  139. def def_op(name, op):
  140.     opname[op] = name
  141.  
  142. def name_op(name, op):
  143.     opname[op] = name
  144.     hasname.append(op)
  145.  
  146. def jrel_op(name, op):
  147.     opname[op] = name
  148.     hasjrel.append(op)
  149.  
  150. def jabs_op(name, op):
  151.     opname[op] = name
  152.     hasjabs.append(op)
  153.  
  154. # Instruction opcodes for compiled code
  155.  
  156. def_op('STOP_CODE', 0)
  157. def_op('POP_TOP', 1)
  158. def_op('ROT_TWO', 2)
  159. def_op('ROT_THREE', 3)
  160. def_op('DUP_TOP', 4)
  161. def_op('ROT_FOUR', 5)
  162.  
  163. def_op('UNARY_POSITIVE', 10)
  164. def_op('UNARY_NEGATIVE', 11)
  165. def_op('UNARY_NOT', 12)
  166. def_op('UNARY_CONVERT', 13)
  167.  
  168. def_op('UNARY_INVERT', 15)
  169.  
  170. def_op('BINARY_POWER', 19)
  171.  
  172. def_op('BINARY_MULTIPLY', 20)
  173. def_op('BINARY_DIVIDE', 21)
  174. def_op('BINARY_MODULO', 22)
  175. def_op('BINARY_ADD', 23)
  176. def_op('BINARY_SUBTRACT', 24)
  177. def_op('BINARY_SUBSCR', 25)
  178. def_op('BINARY_FLOOR_DIVIDE', 26)
  179. def_op('BINARY_TRUE_DIVIDE', 27)
  180. def_op('INPLACE_FLOOR_DIVIDE', 28)
  181. def_op('INPLACE_TRUE_DIVIDE', 29)
  182.  
  183. def_op('SLICE+0', 30)
  184. def_op('SLICE+1', 31)
  185. def_op('SLICE+2', 32)
  186. def_op('SLICE+3', 33)
  187.  
  188. def_op('STORE_SLICE+0', 40)
  189. def_op('STORE_SLICE+1', 41)
  190. def_op('STORE_SLICE+2', 42)
  191. def_op('STORE_SLICE+3', 43)
  192.  
  193. def_op('DELETE_SLICE+0', 50)
  194. def_op('DELETE_SLICE+1', 51)
  195. def_op('DELETE_SLICE+2', 52)
  196. def_op('DELETE_SLICE+3', 53)
  197.  
  198. def_op('INPLACE_ADD', 55)
  199. def_op('INPLACE_SUBTRACT', 56)
  200. def_op('INPLACE_MULTIPLY', 57)
  201. def_op('INPLACE_DIVIDE', 58)
  202. def_op('INPLACE_MODULO', 59)
  203. def_op('STORE_SUBSCR', 60)
  204. def_op('DELETE_SUBSCR', 61)
  205.  
  206. def_op('BINARY_LSHIFT', 62)
  207. def_op('BINARY_RSHIFT', 63)
  208. def_op('BINARY_AND', 64)
  209. def_op('BINARY_XOR', 65)
  210. def_op('BINARY_OR', 66)
  211. def_op('INPLACE_POWER', 67)
  212. def_op('GET_ITER', 68)
  213.  
  214. def_op('PRINT_EXPR', 70)
  215. def_op('PRINT_ITEM', 71)
  216. def_op('PRINT_NEWLINE', 72)
  217. def_op('PRINT_ITEM_TO', 73)
  218. def_op('PRINT_NEWLINE_TO', 74)
  219. def_op('INPLACE_LSHIFT', 75)
  220. def_op('INPLACE_RSHIFT', 76)
  221. def_op('INPLACE_AND', 77)
  222. def_op('INPLACE_XOR', 78)
  223. def_op('INPLACE_OR', 79)
  224. def_op('BREAK_LOOP', 80)
  225.  
  226. def_op('LOAD_LOCALS', 82)
  227. def_op('RETURN_VALUE', 83)
  228. def_op('IMPORT_STAR', 84)
  229. def_op('EXEC_STMT', 85)
  230. def_op('YIELD_STMT', 86)
  231.  
  232. def_op('POP_BLOCK', 87)
  233. def_op('END_FINALLY', 88)
  234. def_op('BUILD_CLASS', 89)
  235.  
  236. HAVE_ARGUMENT = 90              # Opcodes from here have an argument:
  237.  
  238. name_op('STORE_NAME', 90)       # Index in name list
  239. name_op('DELETE_NAME', 91)      # ""
  240. def_op('UNPACK_SEQUENCE', 92)   # Number of tuple items
  241. jrel_op('FOR_ITER', 93)
  242.  
  243. name_op('STORE_ATTR', 95)       # Index in name list
  244. name_op('DELETE_ATTR', 96)      # ""
  245. name_op('STORE_GLOBAL', 97)     # ""
  246. name_op('DELETE_GLOBAL', 98)    # ""
  247. def_op('DUP_TOPX', 99)          # number of items to duplicate
  248. def_op('LOAD_CONST', 100)       # Index in const list
  249. hasconst.append(100)
  250. name_op('LOAD_NAME', 101)       # Index in name list
  251. def_op('BUILD_TUPLE', 102)      # Number of tuple items
  252. def_op('BUILD_LIST', 103)       # Number of list items
  253. def_op('BUILD_MAP', 104)        # Always zero for now
  254. name_op('LOAD_ATTR', 105)       # Index in name list
  255. def_op('COMPARE_OP', 106)       # Comparison operator
  256. hascompare.append(106)
  257. name_op('IMPORT_NAME', 107)     # Index in name list
  258. name_op('IMPORT_FROM', 108)     # Index in name list
  259.  
  260. jrel_op('JUMP_FORWARD', 110)    # Number of bytes to skip
  261. jrel_op('JUMP_IF_FALSE', 111)   # ""
  262. jrel_op('JUMP_IF_TRUE', 112)    # ""
  263. jabs_op('JUMP_ABSOLUTE', 113)   # Target byte offset from beginning of code
  264. jrel_op('FOR_LOOP', 114)        # Number of bytes to skip
  265.  
  266. name_op('LOAD_GLOBAL', 116)     # Index in name list
  267.  
  268. jabs_op('CONTINUE_LOOP', 119)   # Target address
  269. jrel_op('SETUP_LOOP', 120)      # Distance to target address
  270. jrel_op('SETUP_EXCEPT', 121)    # ""
  271. jrel_op('SETUP_FINALLY', 122)   # ""
  272.  
  273. def_op('LOAD_FAST', 124)        # Local variable number
  274. haslocal.append(124)
  275. def_op('STORE_FAST', 125)       # Local variable number
  276. haslocal.append(125)
  277. def_op('DELETE_FAST', 126)      # Local variable number
  278. haslocal.append(126)
  279.  
  280. def_op('SET_LINENO', 127)       # Current line number
  281. SET_LINENO = 127
  282.  
  283. def_op('RAISE_VARARGS', 130)    # Number of raise arguments (1, 2, or 3)
  284. def_op('CALL_FUNCTION', 131)    # #args + (#kwargs << 8)
  285. def_op('MAKE_FUNCTION', 132)    # Number of args with default values
  286. def_op('BUILD_SLICE', 133)      # Number of items
  287.  
  288. def_op('MAKE_CLOSURE', 134)
  289. def_op('LOAD_CLOSURE', 135)
  290. hasfree.append(135)
  291. def_op('LOAD_DEREF', 136)
  292. hasfree.append(136)
  293. def_op('STORE_DEREF', 137)
  294. hasfree.append(137)
  295.  
  296. def_op('CALL_FUNCTION_VAR', 140)     # #args + (#kwargs << 8)
  297. def_op('CALL_FUNCTION_KW', 141)      # #args + (#kwargs << 8)
  298. def_op('CALL_FUNCTION_VAR_KW', 142)  # #args + (#kwargs << 8)
  299.  
  300. def_op('EXTENDED_ARG', 143)
  301. EXTENDED_ARG = 143
  302.  
  303. def _test():
  304.     """Simple test program to disassemble a file."""
  305.     if sys.argv[1:]:
  306.         if sys.argv[2:]:
  307.             sys.stderr.write("usage: python dis.py [-|file]\n")
  308.             sys.exit(2)
  309.         fn = sys.argv[1]
  310.         if not fn or fn == "-":
  311.             fn = None
  312.     else:
  313.         fn = None
  314.     if not fn:
  315.         f = sys.stdin
  316.     else:
  317.         f = open(fn)
  318.     source = f.read()
  319.     if fn:
  320.         f.close()
  321.     else:
  322.         fn = "<stdin>"
  323.     code = compile(source, fn, "exec")
  324.     dis(code)
  325.  
  326. if __name__ == "__main__":
  327.     _test()
  328.